package com.droid.mvvmlib.utils;

import android.app.ActivityManager;
import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;

import com.droid.mvvmlib.log.Logcat;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Android processes
 */
public final class ProcessUtil {
    private static final String TAG = "ProcessUtil";
    private static String mProcessName;
    private static final int DEFAULT_MAX_LINE_LENGTH = 1024;

    public static boolean isMainProcess(Context context) {
        String processName = getCurrentProcessName(context);
        return !TextUtils.isEmpty(processName) && processName.equals(context.getPackageName());
    }

    public static void killSelf() {
        android.os.Process.killProcess(android.os.Process.myPid());
    }

    /**
     * 延迟自杀，使finish有机会执行
     */
    public static void killSelfDelay() {
        // activity finish的动画约400ms，不需要太精确
        killSelf(400);
    }

    public static void killSelf(long delayMs) {
        if (delayMs > 0) {
            new Handler().postDelayed(ProcessUtil::killSelf, delayMs);
        } else {
            killSelf();
        }
    }

    /**
     * 返回当前进程名
     *
     * @return 进程名或空
     */
    public static String getCurrentProcessName(Context context) {
        if (TextUtils.isEmpty(mProcessName)) {
            mProcessName = getCurrentProcessNameUsingProc();

            if (TextUtils.isEmpty(mProcessName)) {
                Logcat.w(TAG, "Could not figure out process name using /proc");
                mProcessName = getCurrentProcessNameUsingActivityManager(context);
                if (TextUtils.isEmpty(mProcessName)) {
                    Logcat.w(TAG, "Could not figure out process name using ActivityManager");
                }
            }
        }
        return mProcessName;
    }

    /**
     * 通过 ActivityManager#getRunningAppProcesses 读取进程名
     */
    private static String getCurrentProcessNameUsingActivityManager(Context context) {
        int pid = android.os.Process.myPid();
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (activityManager == null) {
            Logcat.w(TAG, "ActivityManager#getRunningAppProcesses did not return an entry matching pid = " + pid);
            return null;
        }

        try {
            final List<ActivityManager.RunningAppProcessInfo> runningList = activityManager.getRunningAppProcesses();
            if (runningList != null) {
                for (ActivityManager.RunningAppProcessInfo processInfo : runningList) {
                    if (null == processInfo) {
                        continue;
                    }
                    if (processInfo.pid == pid) {
                        return processInfo.processName;
                    }
                }
            }
            Logcat.w(TAG, "ActivityManager is null when not expected to be!");
        } catch (Exception e) {
            Logcat.w(TAG, "getRunningAppProcesses exception: " + e.getMessage());
        }

        return null;
    }

    /**
     * 从内核的/proc目录读取
     */
    private static String getCurrentProcessNameUsingProc() {
        String processName = "";
        try (FileInputStream fileInputStream = new FileInputStream("/proc/self/cmdline");
             InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
             BufferedReader br = new BufferedReader(inputStreamReader)) {
            final char[] buf = new char[DEFAULT_MAX_LINE_LENGTH];
            int rv = br.read(buf);
            if (rv > 0) {
                processName = new String(buf, 0, rv).trim();
            }
        } catch (IOException e) {
            Logcat.e(TAG, e.getMessage());
        }
        return processName;
    }
}